from pathlib import Path
from typing import Iterable, Any
import re
from pdfminer.high_level import extract_pages


class PdfContentPosition:
    #  x1  y1  x2  y2, 坐标原点在左下角。(x1, y1)为左下角坐标，(x2, y2)为右上角坐标。
    def __init__(self):

        pass
    def get_content_pos(self, pdf_path):
        self.pdf_path = pdf_path
        self.cur_page = 0
        self.word_pos = []

        path = Path(pdf_path).expanduser()
        pages = extract_pages(path)
        
        self._show_ltitem_hierarchy(pages)
        return self.word_pos
    def _match_code(self, text):
        
        pattern = r'(代码_[0-9.]*)[\(（ ]*(\d+)*[分)）:：]*'
        return re.findall(pattern, text)
    
    def _match_question_scores(self,text):
        pattern = r'第(\S)题[\. ]*[\(（](\d+)\s*分\)'
        # matches = re.findall(pattern, text)
        return re.findall(pattern, text)

    def _show_ltitem_hierarchy(self, o: Any, depth=0):
        """Show location and text of LTItem and all its descendants"""
        # 如果要查看输出的内容，取消注释下面的3个print
        if depth == 0:
            # print('element                        x1  y1  x2  y2   text')
            # print('------------------------------ --- --- --- ---- -----')
            pass
        if depth == 1:
            self.cur_page+=1
        text = self._get_optional_text(o)
        pos = self._get_optional_bbox(o)
        
        # print(
        #     f'{self._get_indented_name(o, depth):<30.30s} '
        #     f'{pos} '
        #     f'{text}'
        # )
        if depth == 2:
            title_match = self._match_question_scores(text)
            if title_match:
                self.word_pos.append({'page':self.cur_page, 'pos':pos, 'text':text, 'type':'title', 'score':title_match[0][1]})
            else :
                code_match = self._match_code(text)
                if code_match:
                    self.word_pos.append({'page':self.cur_page, 'pos':pos, 'text':text, 'type':'code', 'score':code_match[0][1]})
            return 
        if isinstance(o, Iterable):
            for i in o:
                self._show_ltitem_hierarchy(i, depth=depth + 1)

    def _get_indented_name(self, o: Any, depth: int) -> str:
        """Indented name of LTItem"""
        return '  ' * depth + o.__class__.__name__

    def _get_optional_bbox(self, o: Any) -> str:
        """Bounding box of LTItem if available, otherwise empty string"""
        if hasattr(o, 'bbox'):
            return ''.join(f'{i:<4.0f}' for i in o.bbox)
        return ''

    def _get_optional_text(self, o: Any) -> str:
        """Text of LTItem if available, otherwise empty string"""
        if hasattr(o, 'get_text'):
            return o.get_text().strip()
        return ''
if __name__ == '__main__':
    # 使用示例
    pdf_path = '/root/k8s-vue/exam-platform-of-big-data/工具函数/autoExam_test.pdf'
    

    pdfPosGetter = PdfContentPosition()
    pos = pdfPosGetter.get_content_pos(pdf_path)
    print(pos)
    
# element                        x1  y1  x2  y2   text
# ------------------------------ --- --- --- ---- -----
# generator                       
#   LTPage                       0   0   200 200  
#     LTTextBoxHorizontal        80  129 120 139  ★ ★ ★
#       LTTextLineHorizontal     80  129 120 139  ★ ★ ★
#         LTChar                 80  129 90  139  ★
#         LTChar                 90  129 95  139  
#         LTChar                 95  129 105 139  ★
#         LTChar                 105 129 110 139  
#         LTChar                 110 129 120 139  ★
#         LTAnno                  
#     LTTextBoxHorizontal        80  109 120 119  成绩：90
#       LTTextLineHorizontal     80  109 120 119  成绩：90
#         LTChar                 80  109 90  119  成
#         LTChar                 90  109 100 119  绩
#         LTChar                 100 109 110 119  ：
#         LTChar                 110 109 115 119  9
#         LTChar                 115 109 120 119  0
#         LTAnno                  
#     LTTextBoxHorizontal        70  89  130 99   阅卷人：张三
#       LTTextLineHorizontal     70  89  130 99   阅卷人：张三
#         LTChar                 70  89  80  99   阅
#         LTChar                 80  89  90  99   卷
#         LTChar                 90  89  100 99   人
#         LTChar                 100 89  110 99   ：
#         LTChar                 110 89  120 99   张
#         LTChar                 120 89  130 99   三
#         LTAnno                  
#     LTTextBoxHorizontal        60  69  146 78   2024-04-30 12:25:18
#       LTTextLineHorizontal     60  69  146 78   2024-04-30 12:25:18
#         LTChar                 60  69  64  78   2
#         LTChar                 64  69  69  78   0
#         LTChar                 69  69  74  78   2
#         LTChar                 74  69  78  78   4
#         LTChar                 78  69  82  78   -
#         LTChar                 82  69  87  78   0
#         LTChar                 87  69  92  78   4
#         LTChar                 92  69  96  78   -
#         LTChar                 96  69  100 78   3
#         LTChar                 100 69  105 78   0
#         LTChar                 105 69  110 78   
#         LTChar                 110 69  114 78   1
#         LTChar                 114 69  118 78   2
#         LTChar                 118 69  123 78   :
#         LTChar                 123 69  128 78   2
#         LTChar                 128 69  132 78   5
#         LTChar                 132 69  136 78   :
#         LTChar                 136 69  141 78   1
#         LTChar                 141 69  146 78   8
#         LTAnno                  
#     LTCurve                    40  40  160 160  
#     LTCurve                    45  45  155 155  